home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / mus / edit / amisox_wav.lha / stat.c < prev    next >
C/C++ Source or Header  |  1992-03-27  |  3KB  |  158 lines

  1.  
  2.  
  3. /*
  4.  * July 5, 1991
  5.  * Copyright 1991 Lance Norskog And Sundry Contributors
  6.  * This source code is freely redistributable and may be used for
  7.  * any purpose.  This copyright notice must be maintained. 
  8.  * Lance Norskog And Sundry Contributors are not responsible for 
  9.  * the consequences of using this software.
  10.  */
  11.  
  12. /*
  13.  * Sound Tools statistics "effect" file.
  14.  *
  15.  * Build various statistics on file and print them.
  16.  * No output.
  17.  */
  18.  
  19. #include "st.h"
  20.  
  21. /* Private data for STAT effect */
  22. typedef struct statstuff {
  23.     long    min, max, mean;        /* amplitudes */
  24.     long    dmin, dmax, dmean;    /* deltas */
  25.     long    last;            /* previous sample */
  26.     int    first;
  27.     int    total;
  28.     int    volume;
  29. } *stat_t;
  30.  
  31. #define    abs(val)    (((val) < 0) ? -(val) : (val))
  32.  
  33. /*
  34.  * Process options
  35.  */
  36. stat_getopts(effp, n, argv) 
  37. eff_t effp;
  38. int n;
  39. char **argv;
  40. {
  41.     stat_t stat = (stat_t) effp->priv;
  42.  
  43.     stat->volume = 0;
  44.     if (n)
  45.         if (strcmp(argv[0], "-V"))
  46.             stat->volume = 1;
  47.         else
  48.             fail("Summary effect takes no options.");
  49. }
  50.  
  51. /*
  52.  * Prepare processing.
  53.  */
  54. stat_start(effp)
  55. eff_t effp;
  56. {
  57.     stat_t stat = (stat_t) effp->priv;
  58.  
  59.     stat->min = stat->dmin = 0x7fffffff;
  60.     stat->max = stat->dmax = 0x80000000;
  61.     stat->first = 1;
  62. }
  63.  
  64. /*
  65.  * Processed signed long samples from ibuf to obuf.
  66.  * Return number of samples processed.
  67.  */
  68.  
  69. stat_flow(effp, ibuf, obuf, isamp, osamp)
  70. eff_t effp;
  71. long *ibuf, *obuf;
  72. int *isamp, *osamp;
  73. {
  74.     stat_t stat = (stat_t) effp->priv;
  75.     int len, done;
  76.     long samp, delta;
  77.     
  78.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  79.     for(done = 0; done < len; done++) {
  80.         /* work in absolute levels for both sample and delta */
  81.         samp = *ibuf++;
  82.             *obuf++ = samp;
  83.  
  84.         samp = abs(samp);
  85.         if (samp < stat->min)
  86.             stat->min = samp;
  87.         if (samp > stat->max)
  88.             stat->max = samp;
  89.         if (stat->first) {
  90.             stat->first = 0;
  91.             stat->mean = samp;
  92.             stat->dmean = 0;
  93.         } else  {
  94.             /* overflow avoidance */
  95.             if ((stat->mean > 0x20000000) || (samp > 0x20000000))
  96.                 stat->mean = stat->mean/2 + samp/2;
  97.             else
  98.                 stat->mean = (stat->mean + samp)/2;
  99.  
  100.             delta = abs(samp - stat->last);
  101.             if (delta < stat->dmin)
  102.                 stat->dmin = delta;
  103.             if (delta > stat->dmax)
  104.                 stat->dmax = delta;
  105.             /* overflow avoidance */
  106.             if ((delta > 0x20000000) || (stat->dmean > 0x20000000))
  107.                 stat->dmean = stat->dmean/2 + delta/2;
  108.             else
  109.                 stat->dmean = (stat->dmean + delta)/2;
  110.         }
  111.         stat->last = samp;
  112.     }
  113.     /* Process all samples */
  114. }
  115.  
  116. /*
  117.  * Do anything required when you stop reading samples.  
  118.  * Don't close input file! 
  119.  */
  120. stat_stop(effp)
  121. eff_t effp;
  122. {
  123.     stat_t stat = (stat_t) effp->priv;
  124.     double amp, range;
  125.  
  126.     stat->min   = RIGHT(stat->min, 16);
  127.     stat->max   = RIGHT(stat->max, 16);
  128.     stat->mean  = RIGHT(stat->mean, 16);
  129.     stat->dmin  = RIGHT(stat->dmin, 16);
  130.     stat->dmax  = RIGHT(stat->dmax, 16);
  131.     stat->dmean = RIGHT(stat->dmean, 16);
  132.  
  133.     range = 32767.0;
  134.  
  135.     amp = - stat->min;
  136.     if (amp < stat->max)
  137.         amp = stat->max;
  138.     /* Just print the volume adjustment */
  139.     if (stat->volume) {
  140.         fprintf(stderr, "%.3f\n", 32767.0/amp);
  141.         return;
  142.     }
  143.     /* print them out */
  144.     fprintf(stderr, "Maximum amplitude: %.3f\n", stat->max/range);
  145.     fprintf(stderr, "Minimum amplitude: %.3f\n", stat->min/range);
  146.     fprintf(stderr, "Mean    amplitude: %.3f\n", stat->mean/range);
  147.  
  148.     fprintf(stderr, "Maximum delta:     %.3f\n", stat->dmax/range);
  149.     fprintf(stderr, "Minimum delta:     %.3f\n", stat->dmin/range);
  150.     fprintf(stderr, "Mean    delta:     %.3f\n", stat->dmean/range);
  151.  
  152.     fprintf(stderr, "Volume adjustment: %.3f\n", 32767.0/amp);
  153. }
  154.  
  155.  
  156.  
  157.  
  158.